#pragma once

#include "base_callback_list.h"
#include "base_noncopyable.h"
#include <nlohmann/json.hpp>
#include <string>
#include <unordered_map>
#include <future>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>

namespace El {
namespace Common {

class Event {
    DISALLOW_COPY_AND_MOVE(Event);

public:
    using Callback = std::function<void(const std::string &eventName, const nlohmann::json &data)>;

    // 获取事件默认实例
    static Event &GetInstance();

    // 获取定制事件实例
    static Event &GetCustomInstance(std::string instanceName);

    Event();

    ~Event();

    // 订阅事件
    // eventName 事件名称
    // callback 事件回调
    // priority 0为最高优先级，默认优先级为100，同个eventName下优先级越高，越先调用
    int32_t Subscribe(const std::string &eventName, const Callback &callback, int32_t priority = 100);

    // 取消订阅事件
    void Unsubscribe(const std::string &eventName, int32_t handle);

    // 通知事件
    // eventName 事件名称
    // data 事件数据
    void Notify(const std::string &eventName, const nlohmann::json &data);

    // 异步通知事件
    // eventName 事件名称
    // data 事件数据
    // 返回一个future，用于等待事件回调完成
    std::future<void> NotifyAsync(const std::string &eventName, const nlohmann::json &data);

    // 判断事件是否为空
    bool IsEmpty(const std::string &eventName) const;

    // 设置线程池大小
    void SetThreadPoolSize(size_t size);

private:
    std::unordered_map<std::string, Base::CallbackList<void, std::string, nlohmann::json>> managers_;

    std::vector<std::thread> workers_;
    std::queue<std::function<void()>> tasks_;
    std::mutex queue_mutex_;
    std::condition_variable condition_;
    bool stop_ = false;

    void initializeThreadPool(size_t size);
    void workerThread();
};

} // namespace Common
} // namespace El